package com.itheima.blog.admin.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itheima.blog.admin.dao.MenuMapper;
import com.itheima.blog.admin.entity.Menu;
import com.itheima.blog.admin.service.MenuService;
import com.itheima.blog.admin.vo.CategoryMenuVO;
import com.itheima.common.constants.SQLConf;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * <p>
 * 菜单表 服务实现类
 * </p>
 *
 * @author xuzhixiang
 * @since 2018年11月23日10:42:30
 */
@Service
public class MenuServiceImpl extends ServiceImpl<MenuMapper, Menu> implements MenuService {


    /*@Override
    public Map<String, Object> getPageList(CategoryMenuVO categoryMenuVO) {
        Map<String, Object> resultMap = new HashMap<>();
        QueryWrapper<Menu> queryWrapper = new QueryWrapper<>();

        if (categoryMenuVO.getMenuLevel() != 0) {
            queryWrapper.eq(SQLConf.MENU_LEVEL, categoryMenuVO.getMenuLevel());
        }

        Page<Menu> page = new Page<>();
        page.setCurrent(categoryMenuVO.getCurrentPage());
        page.setSize(categoryMenuVO.getPageSize());
        queryWrapper.eq(SQLConf.STATUS, EStatus.ENABLE);
        queryWrapper.orderByDesc(SQLConf.SORT);
        IPage<Menu> pageList = page(page, queryWrapper);
        List<Menu> list = pageList.getRecords();

        List<String> ids = new ArrayList<>();
        list.forEach(item -> {
            if (StringUtils.isNotEmpty(item.getParentUid())) {
                ids.add(item.getParentUid());
            }
        });

        if (ids.size() > 0) {
            Collection<Menu> parentList = listByIds(ids);
            Map<String, Menu> map = new HashMap<>();
            parentList.forEach(item -> {
                map.put(item.getUid(), item);
            });

            list.forEach(item -> {
                if (StringUtils.isNotEmpty(item.getParentUid())) {
                    item.setParentCategoryMenu(map.get(item.getParentUid()));
                }
            });

            resultMap.put(SysConf.OTHER_DATA, parentList);
        }
        pageList.setRecords(list);
        resultMap.put(SysConf.DATA, pageList);
        return resultMap;
    }*/

    @Override
    public List<Menu> getAllList(String keyword) {
        QueryWrapper<Menu> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("menu_level", "1");
        if (StringUtils.isNotEmpty(keyword)) {
            queryWrapper.eq("id", keyword);
        }
        queryWrapper.orderByDesc("sort");
        queryWrapper.eq("status", 1);
        queryWrapper.eq("menu_type", 0);
        List<Menu> list = list(queryWrapper);

        //获取所有的ID，去寻找他的子目录
        List<String> ids = new ArrayList<>();
        list.forEach(item -> {
            if (StringUtils.isNotEmpty(item.getId())) {
                ids.add(item.getId());
            }
        });

        QueryWrapper<Menu> childWrapper = new QueryWrapper<>();
        childWrapper.in("parent_id", ids);
        childWrapper.eq("status", 1);
        Collection<Menu> childList = list(childWrapper);

        //获取所有的二级菜单，去寻找他的子按钮
        List<String> secondMenuUids = new ArrayList<>();
        childList.forEach(item -> {
            if (StringUtils.isNotEmpty(item.getId())) {
                secondMenuUids.add(item.getId());
            }
        });

        QueryWrapper<Menu> buttonWrapper = new QueryWrapper<>();
        buttonWrapper.in("parent_id", secondMenuUids);
        buttonWrapper.eq("status", 1);
        Collection<Menu> buttonList = list(buttonWrapper);

        Map<String, List<Menu>> map = new HashMap<>();
        buttonList.forEach(item -> {
            if (StringUtils.isNotEmpty(item.getParentId())) {
                if (map.get(item.getParentId()) == null) {
                    List<Menu> tempList = new ArrayList<>();
                    tempList.add(item);
                    map.put(item.getParentId(), tempList);
                } else {
                    List<Menu> tempList = map.get(item.getParentId());
                    tempList.add(item);
                    map.put(item.getParentId(), tempList);
                }
            }
        });

        // 给二级菜单设置三级按钮
        childList.forEach(item -> {
            if (map.get(item.getId()) != null) {
                List<Menu> tempList = map.get(item.getId());
                Collections.sort(tempList, new Comparator<Menu>() {

                    /*
                     * int compare(CategoryMenu p1, CategoryMenu p2) 返回一个基本类型的整型，
                     * 返回负数表示：p1 小于p2，
                     * 返回0 表示：p1和p2相等，
                     * 返回正数表示：p1大于p2
                     */
                    @Override
                    public int compare(Menu o1, Menu o2) {

                        //按照CategoryMenu的Sort进行降序排列
                        if (o1.getSort() > o2.getSort()) {
                            return -1;
                        }
                        if (o1.getSort().equals(o2.getSort())) {
                            return 0;
                        }
                        return 1;
                    }

                });
                item.setChildCategoryMenu(tempList);
            }
        });


        // 给一级菜单设置二级菜单
        for (Menu parentItem : list) {
            List<Menu> tempList = new ArrayList<>();
            for (Menu item : childList) {

                if (item.getParentId().equals(parentItem.getId())) {
                    tempList.add(item);
                }
            }
            Collections.sort(tempList);
            parentItem.setChildCategoryMenu(tempList);
        }
        return list;
    }

    @Override
    public List<Menu> getButtonAllList(String keyword) {
        QueryWrapper<Menu> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(SQLConf.MENU_LEVEL, "2");
        queryWrapper.orderByDesc(SQLConf.SORT);
        if (StringUtils.isNotEmpty(keyword)) {
            queryWrapper.eq(SQLConf.UID, keyword);
        }
        queryWrapper.eq(SQLConf.STATUS, 1);
        queryWrapper.eq(SQLConf.MENU_TYPE, 0);
        List<Menu> list = list(queryWrapper);

        //获取所有的ID，去寻找他的子目录
        List<String> ids = new ArrayList<>();
        list.forEach(item -> {
            if (StringUtils.isNotEmpty(item.getId())) {
                ids.add(item.getId());
            }
        });

        QueryWrapper<Menu> childWrapper = new QueryWrapper<>();
        childWrapper.in(SQLConf.PARENT_UID, ids);
        childWrapper.eq(SQLConf.STATUS, 1);
        Collection<Menu> childList = list(childWrapper);
        Set<String> secondUidSet = new HashSet<>();
        Map<String, List<Menu>> map = new HashMap<>();
        childList.forEach(item -> {
            if (StringUtils.isNotEmpty(item.getParentId())) {

                secondUidSet.add(item.getParentId());

                if (map.get(item.getParentId()) == null) {
                    List<Menu> tempList = new ArrayList<>();
                    tempList.add(item);
                    map.put(item.getParentId(), tempList);
                } else {
                    List<Menu> tempList = map.get(item.getParentId());
                    tempList.add(item);
                    map.put(item.getParentId(), tempList);
                }
            }
        });

        // 过滤不在Button列表中的二级菜单
        List<Menu> secondCategoryMenuList = new ArrayList<>();
        for (Menu secondCategoryMenu : list) {
            for (String uid : secondUidSet) {
                if (secondCategoryMenu.getId().equals(uid)) {
                    secondCategoryMenuList.add(secondCategoryMenu);
                    break;
                }
            }
        }

        // 给二级菜单设置三级按钮
        secondCategoryMenuList.forEach(item -> {
            if (map.get(item.getId()) != null) {
                List<Menu> tempList = map.get(item.getId());
                Collections.sort(tempList);
                item.setChildCategoryMenu(tempList);
            }
        });
        return list;
    }

    @Override
    public void addCategoryMenu(CategoryMenuVO categoryMenuVO) {
        //如果是一级菜单，将父ID清空
        if (categoryMenuVO.getMenuLevel() == 1) {
            categoryMenuVO.setParentUid("");
        }
        Menu categoryMenu = new Menu();
        categoryMenu.setParentId(categoryMenuVO.getParentUid());
        categoryMenu.setSort(categoryMenuVO.getSort());
        categoryMenu.setIcon(categoryMenuVO.getIcon());
        categoryMenu.setSummary(categoryMenuVO.getSummary());
        categoryMenu.setMenuLevel(categoryMenuVO.getMenuLevel());
        categoryMenu.setMenuType(categoryMenuVO.getMenuType());
        categoryMenu.setName(categoryMenuVO.getName());
        categoryMenu.setUrl(categoryMenuVO.getUrl());
        categoryMenu.setIsShow(categoryMenuVO.getIsShow());
        categoryMenu.setUpdateTime(new Date());
        categoryMenu.setIsJumpExternalUrl(categoryMenuVO.getIsJumpExternalUrl());
        save(categoryMenu);
    }

    @Override
    public void editCategoryMenu(CategoryMenuVO categoryMenuVO) {
        Menu categoryMenu = getById(categoryMenuVO.getUid());
        categoryMenu.setParentId(categoryMenuVO.getParentUid());
        categoryMenu.setSort(categoryMenuVO.getSort());
        categoryMenu.setIcon(categoryMenuVO.getIcon());
        categoryMenu.setSummary(categoryMenuVO.getSummary());
        categoryMenu.setMenuLevel(categoryMenuVO.getMenuLevel());
        categoryMenu.setMenuType(categoryMenuVO.getMenuType());
        categoryMenu.setName(categoryMenuVO.getName());
        categoryMenu.setUrl(categoryMenuVO.getUrl());
        categoryMenu.setIsShow(categoryMenuVO.getIsShow());
        categoryMenu.setUpdateTime(new Date());
        categoryMenu.setIsJumpExternalUrl(categoryMenuVO.getIsJumpExternalUrl());
        updateById(categoryMenu);
        // 修改成功后，需要删除redis中所有的admin访问路径
//        deleteAdminVisitUrl();
    }

    @Override
    public void deleteCategoryMenu(CategoryMenuVO categoryMenuVO) {
        QueryWrapper<Menu> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(SQLConf.STATUS, 1);
        queryWrapper.in(SQLConf.PARENT_UID, categoryMenuVO.getUid());
        Long menuCount = count(queryWrapper);
        if (menuCount > 0) {
            return;
        }
        Menu categoryMenu = getById(categoryMenuVO.getUid());
        categoryMenu.setStatus(0);
        categoryMenu.setUpdateTime(new Date());
        updateById(categoryMenu);
        // 修改成功后，需要删除redis中所有的admin访问路径
//        deleteAdminVisitUrl();
    }

    @Override
    public void stickCategoryMenu(CategoryMenuVO categoryMenuVO) {
        Menu categoryMenu = getById(categoryMenuVO.getUid());
        //查找出最大的那一个
        QueryWrapper<Menu> queryWrapper = new QueryWrapper<>();
        //如果是二级菜单 或者 按钮，就在当前的兄弟中，找出最大的一个
        if (categoryMenu.getMenuLevel() == 2 || categoryMenu.getMenuType() == 1) {
            queryWrapper.eq(SQLConf.PARENT_UID, categoryMenu.getParentId());
        }
        queryWrapper.eq(SQLConf.MENU_LEVEL, categoryMenu.getMenuLevel());
        queryWrapper.orderByDesc(SQLConf.SORT);
        queryWrapper.last("limit 1");
        Menu maxSort = getOne(queryWrapper);
        if (StringUtils.isEmpty(maxSort.getId())) {
            return ;
        }
        Integer sortCount = maxSort.getSort() + 1;
        categoryMenu.setSort(sortCount);
        categoryMenu.setUpdateTime(new Date());
        updateById(categoryMenu);
    }

    /**
     * 删除Redis中管理员的访问路径
     */
//    private void deleteAdminVisitUrl() {
//        Set<String> keys = redisUtil.keys(RedisConf.ADMIN_VISIT_MENU + "*");
//        redisUtil.delete(keys);
//    }
}